//
// Created by 29108 on 2025/7/15.
//

#include "core_services/api_gateway/circuit_breaker.h"
#include "common/logger/logger.h"
#include "common/config/config_manager.h"
#include <chrono>

namespace core_services {
    namespace api_gateway {
        // ==================== Config静态方法实现 ====================

        /**
         * @brief 从ConfigManager加载熔断器配置
         * @details 从配置管理器中读取熔断器相关配置参数
         * @return 熔断器配置对象
         */
        CircuitBreaker::Config CircuitBreaker::Config::fromConfigManager() {
            auto& config_manager = common::config::ConfigManager::getInstance();
            Config config;

            // 基础熔断参数
            config.failure_threshold = config_manager.get<int>("circuit_breaker.failure_threshold", 5);
            config.timeout = std::chrono::seconds(config_manager.get<int>("circuit_breaker.timeout_seconds", 30));
            config.success_threshold = config_manager.get<int>("circuit_breaker.success_threshold", 3);

            // 高级熔断参数
            config.failure_rate_threshold = config_manager.get<double>("circuit_breaker.failure_rate_threshold", 0.5);
            config.min_request_threshold = config_manager.get<int>("circuit_breaker.min_request_threshold", 10);
            config.response_timeout = std::chrono::milliseconds(
                config_manager.get<int>("circuit_breaker.response_timeout_ms", 5000));

            // 慢调用检测
            config.enable_slow_call_detection = config_manager.get<bool>("circuit_breaker.enable_slow_call_detection", true);
            config.slow_call_threshold = std::chrono::milliseconds(
                config_manager.get<int>("circuit_breaker.slow_call_threshold_ms", 3000));

            LOG_INFO("熔断器配置加载完成");
            return config;
        }

        /**
         * @brief 验证熔断器配置的有效性
         * @details 检查各项配置参数是否合法
         * @return true表示配置有效，false表示配置无效
         */
        bool CircuitBreaker::Config::validate() const {
            if (failure_threshold <= 0) {
                LOG_ERROR("失败阈值必须大于0");
                return false;
            }

            if (timeout.count() <= 0) {
                LOG_ERROR("熔断超时时间必须大于0");
                return false;
            }

            if (success_threshold <= 0) {
                LOG_ERROR("成功阈值必须大于0");
                return false;
            }

            if (failure_rate_threshold <= 0 || failure_rate_threshold > 1.0) {
                LOG_ERROR("失败率阈值必须在(0,1]范围内");
                return false;
            }

            if (min_request_threshold <= 0) {
                LOG_ERROR("最小请求数阈值必须大于0");
                return false;
            }

            if (response_timeout.count() <= 0) {
                LOG_ERROR("响应超时时间必须大于0");
                return false;
            }

            if (enable_slow_call_detection && slow_call_threshold.count() <= 0) {
                LOG_ERROR("慢调用阈值必须大于0");
                return false;
            }

            return true;
        }

        // ==================== CircuitBreaker主类实现 ====================

        /**
         * @brief 熔断器构造函数
         * @param config 熔断器配置
         * @details 初始化熔断器，设置初始状态为关闭
         * @throws std::invalid_argument 当配置无效时抛出异常
         */
        CircuitBreaker::CircuitBreaker(const Config &config)
        : config_(config), state_(State::CLOSED) {

            if (!config_.validate()) {
                throw std::invalid_argument("熔断器配置无效");
            }

            state_change_time_ = std::chrono::steady_clock::now();
            LOG_INFO("熔断器初始化完成，初始状态: 关闭");
        }


        CircuitBreaker::~CircuitBreaker() {
            LOG_INFO("熔断器已销毁");
        }

        void CircuitBreaker::recordSuccess() {
            std::unique_lock<std::shared_mutex> lock(state_mutex_);

            // 更新统计信息
            successful_requests_++;
            total_requests_++;

            // 如果处于半开启状态，检查是否应该转换到关闭状态
            if (state_ == State::HALF_OPEN) {
                half_open_success_count_++;
                half_open_request_count_++;

                if (shouldTransitionToClosed()) {
                    transitionToState(State::CLOSED);
                }
            }
        }

        void CircuitBreaker::recordFailure(const std::exception_ptr &exception) {
            std::unique_lock<std::shared_mutex> lock(state_mutex_);

            // 更新统计信息
            failed_requests_++;
            total_requests_++;
            last_failure_time_ = std::chrono::steady_clock::now();

            // 如果处于半开启状态，立即转换到开启状态
            if (state_ == State::HALF_OPEN) {
                half_open_request_count_++;
                transitionToState(State::OPEN);
                return;
            }

            // 如果处于关闭状态，检查是否应该转换到开启状态
            if (state_ == State::CLOSED && shouldTransitionToOpen()) {
                transitionToState(State::OPEN);
            }
        }

        void CircuitBreaker::recordSlowCall(std::chrono::milliseconds duration) {
            if (!config_.enable_slow_call_detection) {
                return;
            }

            std::unique_lock<std::shared_mutex> lock(state_mutex_);

            // 更新统计信息
            slow_requests_++;

            // 如果处于关闭状态且慢调用率超过阈值，考虑转换到开启状态
            if (state_ == State::CLOSED && total_requests_ >= config_.min_request_threshold) {
                double slow_rate = static_cast<double>(slow_requests_) / total_requests_;
                if (slow_rate >= config_.failure_rate_threshold) {
                    LOG_WARNING("慢调用率过高: " + std::to_string(slow_rate * 100) + "%，触发熔断");
                    transitionToState(State::OPEN);
                }
            }
        }

        CircuitBreaker::State CircuitBreaker::getState() const {
            // 使用独占锁避免锁升级问题
            std::unique_lock<std::shared_mutex> lock(state_mutex_);

            // 如果处于开启状态，检查是否应该转换到半开启状态
            if (state_ == State::OPEN && shouldTransitionToHalfOpen()) {
                const_cast<CircuitBreaker*>(this)->transitionToState(State::HALF_OPEN);
            }

            return state_;
        }

        bool CircuitBreaker::shouldTransitionToHalfOpen() const {
            auto now = std::chrono::steady_clock::now();
            auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - state_change_time_);
            return elapsed >= config_.timeout;
        }

        bool CircuitBreaker::shouldTransitionToOpen() const {
            // 检查是否达到最小请求数阈值
            if (total_requests_ < config_.min_request_threshold) {
                return false;
            }

            // 检查失败次数是否超过阈值
            if (failed_requests_ >= config_.failure_threshold) {
                return true;
            }

            // 检查失败率是否超过阈值
            double failure_rate = static_cast<double>(failed_requests_) / total_requests_;
            return failure_rate >= config_.failure_rate_threshold;
        }

        bool CircuitBreaker::shouldTransitionToClosed() const {
            return half_open_success_count_ >= config_.success_threshold;
        }

        void CircuitBreaker::transitionToState(State new_state) {
            if (state_ == new_state) {
                return;
            }

            std::string old_state_str = stateToString(state_);
            std::string new_state_str = stateToString(new_state);

            state_ = new_state;
            state_change_time_ = std::chrono::steady_clock::now();

            LOG_INFO("熔断器状态变更: " + old_state_str + " -> " + new_state_str);

            // 重置相关计数器
            if (new_state == State::HALF_OPEN) {
                half_open_success_count_ = 0;
                half_open_request_count_ = 0;
            } else if (new_state == State::CLOSED) {
                // 重置统计信息
                failed_requests_ = 0;
                successful_requests_ = 0;
                total_requests_ = 0;
                slow_requests_ = 0;
            }
        }

        std::string CircuitBreaker::stateToString(State state) const {
            switch (state) {
                case State::CLOSED: return "关闭";
                case State::OPEN: return "开启";
                case State::HALF_OPEN: return "半开启";
                default: return "未知";
            }
        }
    }
}